home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
mac
/
files
/
t_sys5
/
92052tar.gz
/
920528.tar
/
mail_bbs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-08
|
5KB
|
198 lines
/* @(#) $Header: mail_bbs.c,v 1.9 92/01/08 13:45:23 deyke Exp $ */
/* BBS Mail Delivery Agent */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "global.h"
#include "mbuf.h"
#include "transport.h"
#include "mail.h"
struct mesg {
int state;
#define BBS_OPEN_STATE 0
#define BBS_COMMAND_STATE 1
#define BBS_SUBJECT_STATE 2
#define BBS_SEND_STATE 3
#define BBS_UNLK_STATE 4
#define BBS_QUIT_STATE 5
char buf[1024];
int cnt;
FILE * fp;
struct mailsys *sp;
struct transport_cb *tp;
};
static void mail_bbs_transaction __ARGS((struct mesg *mp));
static void mail_bbs_recv_upcall __ARGS((struct transport_cb *tp, int cnt));
static void mail_bbs_send_upcall __ARGS((struct transport_cb *tp, int cnt));
static void mail_bbs_state_upcall __ARGS((struct transport_cb *tp));
/*---------------------------------------------------------------------------*/
static void mail_bbs_transaction(mp)
struct mesg *mp;
{
char tmp[1024];
struct mailjob *jp;
struct stat statbuf;
struct tm *tm;
jp = mp->sp->jobs;
switch (mp->state) {
case BBS_OPEN_STATE:
if (mp->buf[mp->cnt-1] == '>') {
nextjob:
mp->state = BBS_COMMAND_STATE;
sprintf(tmp,
"S %s @ %s < %s\n",
get_user_from_path(jp->to),
get_host_from_path(jp->to),
get_user_from_path(jp->from));
transport_send(mp->tp, qdata(tmp, strlen(tmp)));
}
break;
case BBS_COMMAND_STATE:
mp->state = BBS_SUBJECT_STATE;
sprintf(tmp, "%s\n", *jp->subject ? jp->subject : "no subject");
transport_send(mp->tp, qdata(tmp, strlen(tmp)));
break;
case BBS_SUBJECT_STATE:
if (!stat(jp->cfile, &statbuf) && (mp->fp = fopen(jp->dfile, "r"))) {
mp->state = BBS_SEND_STATE;
while (fgets(tmp, sizeof(tmp), mp->fp) && *tmp != '\n') ;
tm = gmtime(&statbuf.st_mtime);
sprintf(tmp,
"R:%02d%02d%02d/%02d%02dz @%-6s [WAMPES BBS Mailer]\n",
tm->tm_year % 100,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
Hostname);
transport_send(mp->tp, qdata(tmp, strlen(tmp)));
} else {
mp->state = BBS_QUIT_STATE;
transport_close(mp->tp);
}
break;
case BBS_SEND_STATE:
break;
case BBS_UNLK_STATE:
if (mp->buf[mp->cnt-1] == '>') {
unlink(jp->cfile);
unlink(jp->dfile);
unlink(jp->xfile);
mp->sp->jobs = jp->next;
free(jp);
if (jp = mp->sp->jobs) goto nextjob;
mp->state = BBS_QUIT_STATE;
transport_close(mp->tp);
}
break;
case BBS_QUIT_STATE:
break;
}
}
/*---------------------------------------------------------------------------*/
static void mail_bbs_recv_upcall(tp, cnt)
struct transport_cb *tp;
int cnt;
{
int c;
struct mbuf *bp;
struct mesg *mp;
mp = (struct mesg *) tp->user;
mp->sp->state = MS_TALKING;
transport_recv(tp, &bp, 0);
while ((c = PULLCHAR(&bp)) != -1)
if (c == '\n') {
mp->buf[mp->cnt] = '\0';
mail_bbs_transaction(mp);
mp->cnt = 0;
}
else if (mp->cnt < sizeof(mp->buf) - 1)
mp->buf[mp->cnt++] = c;
}
/*---------------------------------------------------------------------------*/
static void mail_bbs_send_upcall(tp, cnt)
struct transport_cb *tp;
int cnt;
{
char *p;
int c;
struct mbuf *bp;
struct mesg *mp;
mp = (struct mesg *) tp->user;
if (mp->state != BBS_SEND_STATE || cnt <= 0) return;
if (!(bp = alloc_mbuf(cnt))) return;
p = bp->data;
while (p - bp->data < cnt && (c = getc(mp->fp)) != EOF)
if (c && c != '\004' && c != '\032') *p++ = c;
if (bp->cnt = p - bp->data)
transport_send(tp, bp);
else
free_p(bp);
if (c == EOF) {
fclose(mp->fp);
mp->fp = 0;
transport_send(mp->tp, qdata("\032\n", 2));
mp->state = BBS_UNLK_STATE;
}
}
/*---------------------------------------------------------------------------*/
static void mail_bbs_state_upcall(tp)
struct transport_cb *tp;
{
struct mesg *mp;
if (mp = (struct mesg *) tp->user) {
if (mp->fp) fclose(mp->fp);
if (!mp->sp->jobs)
mp->sp->state = MS_SUCCESS;
else
mailer_failed(mp->sp);
free(mp);
}
transport_del(tp);
}
/*---------------------------------------------------------------------------*/
void mail_bbs(sp)
struct mailsys *sp;
{
struct mesg *mp;
mp = calloc(1, sizeof(*mp));
mp->sp = sp;
if (mp->tp = transport_open(sp->protocol, sp->address, mail_bbs_recv_upcall, mail_bbs_send_upcall, mail_bbs_state_upcall, (char *) mp)) {
mp->tp->recv_mode = EOL_LF;
mp->tp->send_mode = strcmp(sp->protocol, "tcp") ? EOL_CR : EOL_CRLF;
transport_set_timeout(mp->tp, 3600);
} else {
mailer_failed(sp);
free(mp);
}
}